/* Copyright 2009
 *
 * This program and the accompanying materials
 * are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * Contributors:
 * 	   IBM Corporation - initial API and implementation for JDT/DLTK
 *     Sean W. Quinn - initial adoption for use with PHP from various sources.
 */
package org.eclipse.php.internal.ui.preferences.formatter.profile;

import java.util.Iterator;
import java.util.Map;

import org.eclipse.dltk.ui.formatter.IProfile;
import org.eclipse.dltk.ui.formatter.IProfileVersioner;
import org.eclipse.php.core.formatter.PHPCodeFormatterConstants;
import org.eclipse.php.internal.core.PHPCoreConstantsExt;
import org.eclipse.php.internal.formatter.PHPFormatterConstants;

/**
 * <p>
 * Implementation of the {@link PHPProfileVersioner} interface.
 * </p>
 *
 * @author Sean W. Quinn (swquinn@gmail.com)
 */
public class PHPProfileVersioner implements IProfileVersioner {

  public static final String CODE_FORMATTER_PROFILE_KIND = "CodeFormatterProfile"; //$NON-NLS-1$

  private static final int VERSION_1 = 1; // < 20040113 (includes M6)

  private static final int CURRENT_VERSION = VERSION_1;

  /**
   *
   */
  public String getFormatterId() {
    // TODO Auto-generated method stub
    return null;
  }

  public int getFirstVersion() {
    return VERSION_1;
  }

  public int getCurrentVersion() {
    return CURRENT_VERSION;
  }

  /**
   * {@inheritDoc}
   */
  public String getProfileKind() {
    return CODE_FORMATTER_PROFILE_KIND;
  }

  public void update(final IProfile profile) {
    if (profile instanceof CustomProfile) {
      final CustomProfile customProfile = (CustomProfile) profile;
      final Map<String, String> oldSettings = customProfile.getSettings();
      final Map<String, String> newSettings = updateAndComplete(oldSettings, customProfile.getVersion());
      customProfile.setVersion(CURRENT_VERSION);
      customProfile.setSettings(newSettings);
    }
  }

  private static Map updateAndComplete(final Map<String, String> oldSettings, final int version) {
    final Map newSettings = PHPFormatterProfileManager.getDefaultSettings();

    switch (version) {
      default:
        for (final Iterator iter = oldSettings.keySet().iterator(); iter.hasNext();) {
          final String key = (String) iter.next();
          if (!newSettings.containsKey(key))
            continue;

          final String value = (String) oldSettings.get(key);
          if (value != null) {
            newSettings.put(key, value);
          }
        }

    }
    return newSettings;
  }

  public static int getVersionStatus(CustomProfile profile) {
    final int version = profile.getVersion();
    if (version < CURRENT_VERSION)
      return -1;
    else if (version > CURRENT_VERSION)
      return 1;
    else
      return 0;
  }

  private static void mapOldValueRangeToNew(Map settings, String oldKey, String[] oldValues, String newKey,
      String[] newValues) {

    if (!settings.containsKey(oldKey))
      return;

    final String value = ((String) settings.get(oldKey));

    if (value == null)
      return;

    for (int i = 0; i < oldValues.length; i++) {
      if (value.equals(oldValues[i])) {
        settings.put(newKey, newValues[i]);
      }
    }

  }

  private static void duplicate(Map settings, String existingKey, String newKey) {
    checkAndReplace(settings, existingKey, new String[] { newKey });
  }

  private static void checkAndReplace(Map settings, String oldKey, String newKey) {
    checkAndReplace(settings, oldKey, new String[] { newKey });
  }

  private static void checkAndReplace(Map settings, String oldKey, String newKey1, String newKey2) {
    checkAndReplace(settings, oldKey, new String[] { newKey1, newKey2 });
  }

  private static void checkAndReplace(Map settings, String oldKey, String[] newKeys) {
    if (!settings.containsKey(oldKey))
      return;

    final String value = (String) settings.get(oldKey);

    if (value == null)
      return;

    for (int i = 0; i < newKeys.length; i++) {
      settings.put(newKeys[i], value);
    }
  }

  private static void checkAndReplaceBooleanWithINSERT(Map settings, String oldKey, String newKey) {
    if (!settings.containsKey(oldKey))
      return;

    String value = (String) settings.get(oldKey);

    if (value == null)
      return;

    if (PHPCodeFormatterConstants.TRUE.equals(value))
      value = PHPFormatterConstants.INSERT;
    else
      value = PHPFormatterConstants.DO_NOT_INSERT;

    settings.put(newKey, value);
  }

  /* old format constant values */

  private static final String FORMATTER_METHOD_DECLARATION_ARGUMENTS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.method_declaration_arguments_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_MESSAGE_SEND_ARGUMENTS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.message_send_arguments_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_MESSAGE_SEND_SELECTOR_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.message_send_selector_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_QUALIFIED_ALLOCATION_EXPRESSION_ARGUMENTS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.qualified_allocation_expression_arguments_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_TYPE_DECLARATION_SUPERCLASS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.type_declaration_superclass_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_TYPE_DECLARATION_SUPERINTERFACES_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.type_declaration_superinterfaces_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_METHOD_THROWS_CLAUSE_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.method_throws_clause_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_CONDITIONAL_EXPRESSION_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.conditional_expression_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_ALLOCATION_EXPRESSION_ARGUMENTS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.allocation_expression_arguments_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_COMPACT_IF_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.compact_if_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_ARRAY_INITIALIZER_EXPRESSIONS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.array_initializer_expressions_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_BINARY_EXPRESSION_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.binary_expression_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_EXPLICIT_CONSTRUCTOR_ARGUMENTS_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.explicit_constructor_arguments_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_ANONYMOUS_TYPE_DECLARATION_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.anonymous_type_declaration_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_ARRAY_INITIALIZER_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.array_initializer_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_BLOCK_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.block_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_METHOD_DECLARATION_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.method_declaration_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_TYPE_DECLARATION_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.type_declaration_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_SWITCH_BRACE_POSITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.switch_brace_position"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_constructor_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MESSAGESEND_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_messagesend_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_OPEN_PAREN_IN_PARENTHESIZED_EXPRESSION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_open_paren_in_parenthesized_expression"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_MESSAGE_SEND = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_opening_paren_in_message_send"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_MESSAGE_SEND = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_closing_paren_in_message_send"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_constructor_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MESSAGESEND_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_messagesend_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_MESSAGE_SEND = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_message_send"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_closing_paren"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_FIRST_ARGUMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_first_argument"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_between_empty_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_WITHIN_MESSAGE_SEND = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_within_message_send"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_BLOCK_CLOSE_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_block_close_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_ANONYMOUS_TYPE_OPEN_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_anonymous_type_open_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_BLOCK_OPEN_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_block_open_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_CATCH_EXPRESSION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_catch_expression"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_CONSTRUCTOR_DECLARATION_OPEN_PAREN = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_constructor_declaration_open_paren"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_FIRST_INITIALIZER = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_first_initializer"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_FOR_PAREN = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_for_paren"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_IF_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_if_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_METHOD_DECLARATION_OPEN_PAREN = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_method_declaration_open_paren"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_METHOD_OPEN_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_method_open_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_OPEN_PAREN_IN_PARENTHESIZED_EXPRESSION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_open_paren_in_parenthesized_expression"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_SWITCH_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_switch_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_SWITCH_OPEN_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_switch_open_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_SYNCHRONIZED_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_synchronized_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_TYPE_OPEN_BRACE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_type_open_brace"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_WHILE_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_while_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BETWEEN_BRACKETS_IN_ARRAY_REFERENCE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_between_brackets_in_array_reference";//$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARRAY_INITIALIZER = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_between_empty_array_initializer"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_MESSAGESEND_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_between_empty_messagesend_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_CATCH_EXPRESSION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_catch_expression"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_FOR_PARENS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_for_parens"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_IF_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_if_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_SWITCH_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_switch_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_SYNCHRONIZED_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_synchronized_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_IN_WHILE_CONDITION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_in_while_condition"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_BRACKET_IN_ARRAY_REFERENCE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_bracket_in_array_reference";//$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_BRACKET_IN_ARRAY_TYPE_REFERENCE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_bracket_in_array_type_reference"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATORS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_assignment_operators"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATORS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_assignment_operators"; //$NON-NLS-1$
  private static final String FORMATTER_FORMAT_GUARDIAN_CLAUSE_ON_ONE_LINE = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.format_guardian_clause_on_one_line"; //$NON-NLS-1$
  private static final String FORMATTER_ARRAY_INITIALIZER_CONTINUATION_INDENTATION = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.array_initializer_continuation_indentation"; //$NON-NLS-1$
  private static final String FORMATTER_TYPE_MEMBER_ALIGNMENT = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.type_member_alignment"; //$NON-NLS-1$
  private static final String FORMATTER_MULTICOLUMN = "256"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_THROWS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_method_throws"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_THROWS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_method_throws"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_method_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_method_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICITCONSTRUCTORCALL_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICITCONSTRUCTORCALL_ARGUMENTS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_THROWS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_after_comma_in_constructor_throws"; //$NON-NLS-1$
  private static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_THROWS = PHPCoreConstantsExt.PLUGIN_ID
      + ".formatter.insert_space_before_comma_in_constructor_throws"; //$NON-NLS-1$
  private static final String FORMATTER_NO_ALIGNMENT = "0";//$NON-NLS-1$
}